package com.cskaoyan.mall.cart.service.impl;

import com.cskaoyan.mall.cart.api.dto.CartInfoDTO;
import com.cskaoyan.mall.cart.client.ProductApiClient;
import com.cskaoyan.mall.cart.converter.SkuInfoConverter;
import com.cskaoyan.mall.cart.service.CartService;
import com.cskaoyan.mall.common.constant.CodeEnum;
import com.cskaoyan.mall.common.constant.RedisConst;
import com.cskaoyan.mall.common.constant.ResultCodeEnum;
import com.cskaoyan.mall.common.execption.BusinessException;
import com.cskaoyan.mall.product.dto.SkuInfoDTO;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class CartServiceImpl implements CartService {
    @Autowired
    RedissonClient redissonClient;
    @Autowired
    ProductApiClient productApiClient;
    @Autowired
    SkuInfoConverter skuInfoConverter;
    @Override
    public void addToCart(Long skuId, String userId, Integer skuNum) {
        //这里面的业务逻辑主要是，，，，，
        //查询是否有对应的skuId，如果有就数量+1，如果没有就向其中添加即可
        RMap<Long, CartInfoDTO> cartGoods = redissonClient.getMap(RedisConst.ORDER_TRADE_CODE_PREFIX + userId);
        CartInfoDTO cartInfoDTO = cartGoods.get(skuId);
        if (cartInfoDTO!=null){
            cartInfoDTO.setSkuNum(cartInfoDTO.getSkuNum()+skuNum);
            cartInfoDTO.setUpdateTime(new Date());
            cartGoods.put(skuId,cartInfoDTO);
        }else {
            //调用接口
            SkuInfoDTO skuInfo = productApiClient.getSkuInfo(skuId);
            CartInfoDTO createCartInfoDTO = skuInfoConverter.skuInfoToCartInfo(skuInfo, skuNum, skuId, userId);
            cartGoods.put(skuId,createCartInfoDTO);
        }


    }

    @Override
    public List<CartInfoDTO> getCartList(String userId, String userTempId) {
        //分情况，是否登录，
        //未登录
        RMap<Long, CartInfoDTO> userTempIdBucket = redissonClient.getMap(RedisConst.ORDER_TRADE_CODE_PREFIX + userTempId);
        RMap<Long, CartInfoDTO> userIdBucket = redissonClient.getMap(RedisConst.ORDER_TRADE_CODE_PREFIX + userId);
        List<CartInfoDTO> userTempList= userTempIdBucket.readAllValues().stream().collect(Collectors.toList());
        if (StringUtils.isBlank(userId)){
            return userTempList;
        }
        //如果登录，是否在userTempId里面存的还有数据
        List<CartInfoDTO> userList=userIdBucket.readAllValues().stream().collect(Collectors.toList());
        if (userTempIdBucket.isEmpty()){
            return userList;
        }

        //如果有需要合并的话
        List<CartInfoDTO> all=margeList(userTempList,userList,userIdBucket);
        userTempIdBucket.delete();
        
        return all;
    }

    private List<CartInfoDTO> margeList(List<CartInfoDTO> userTempList, List<CartInfoDTO> userList, RMap<Long, CartInfoDTO> userIdBucket) {
        Map<Long,CartInfoDTO> resultMap=new HashMap<>();
        userTempList.forEach(item->{
            CartInfoDTO cartInfoDTO = resultMap.get(item.getSkuId());
            if (cartInfoDTO !=null){
                cartInfoDTO.setSkuNum(cartInfoDTO.getSkuNum()+item.getSkuNum());
            }else {
                resultMap.put(item.getSkuId(),item);

            }
        });

        userList.forEach(item->{
            CartInfoDTO cartInfoDTO = resultMap.get(item.getSkuId());
            if (cartInfoDTO !=null){
                cartInfoDTO.setSkuNum(cartInfoDTO.getSkuNum()+item.getSkuNum());
            }else {
                resultMap.put(item.getSkuId(),item);
            }
        });

        userIdBucket.putAll(resultMap);
        return new ArrayList<>(resultMap.values());
    }

    @Override
    public void checkCart(String userId, Integer isChecked, Long skuId) {
        RMap<Long, CartInfoDTO> userIdMap = redissonClient.getMap(RedisConst.ORDER_TRADE_CODE_PREFIX + userId);
        CartInfoDTO cartInfoDTO = userIdMap.get(skuId);
        if (cartInfoDTO!=null){
            cartInfoDTO.setIsChecked(isChecked);
            userIdMap.put(skuId, cartInfoDTO);
        }else {
            throw new BusinessException(ResultCodeEnum.ILLEGAL_REQUEST);
        }

    }

    @Override
    public void deleteCart(Long skuId, String userId) {
        RMap<Long, CartInfoDTO> userIdMap = redissonClient.getMap(RedisConst.ORDER_TRADE_CODE_PREFIX + userId);
        userIdMap.remove(skuId);
    }

    @Override
    public void deleteChecked(String userId) {
        RMap<Long, CartInfoDTO> userIdMap = redissonClient.getMap(RedisConst.ORDER_TRADE_CODE_PREFIX + userId);
        List<Long> checkedIdList=new ArrayList<>();
        userIdMap.forEach((skuId,cartInfoDTO)->{
            if (cartInfoDTO.getIsChecked()==1){
                checkedIdList.add(skuId);
            }
        });
        checkedIdList.forEach(skuId->{
            userIdMap.remove(skuId);
        });
    }

    @Override
    public List<CartInfoDTO> getCartCheckedList(String userId) {
        //获取被选中的列表,从redis中获取
        RMap<Long, CartInfoDTO> map = redissonClient.getMap(RedisConst.ORDER_TRADE_CODE_PREFIX + userId);

        List<CartInfoDTO> result=new ArrayList<>();
        map.forEach((skuId,cartInfo)->{
            if (cartInfo.getIsChecked()==1){
                result.add(cartInfo);
            }
        });

        return result;
    }

    @Override
    public void delete(String userId, List<Long> skuIds) {
        RMap<Long, CartInfoDTO> cartMap = redissonClient.getMap(RedisConst.ORDER_TRADE_CODE_PREFIX + userId);
        for (Long skuId : skuIds) {
            cartMap.remove(skuId);
        }
    }

    @Override
    public void refreshCartPrice(String userId, Long skuId) {
        //要查数据库，更新数据
        SkuInfoDTO skuInfo = productApiClient.getSkuInfo(skuId);
        RMap<Long, CartInfoDTO> cartMap = redissonClient.getMap(RedisConst.ORDER_TRADE_CODE_PREFIX + userId);
        CartInfoDTO cartInfoDTO = cartMap.get(skuId);
        cartInfoDTO.setCartPrice(skuInfo.getPrice());
        cartMap.put(skuId,cartInfoDTO);
    }
}
